package com.thkj.framework.base;

import java.beans.PropertyEditorSupport;
import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.sql.Timestamp;
import java.text.SimpleDateFormat;
import java.util.Date;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.apache.commons.io.FileUtils;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.propertyeditors.CustomDateEditor;
import org.springframework.web.bind.WebDataBinder;
import org.springframework.web.bind.annotation.InitBinder;

import dp.R;
import dp.util.CookieUtil;
import dp.util.DateEditor;
import dp.util.JsonUtil;
import dp.util.ServletUtil;
import dp.util.SpringUtil;

/**
 *
 * @author chensh
 */
public abstract class BaseController {
    protected final Logger logger = LoggerFactory.getLogger(this.getClass());
    protected static final String HEADER_IFMODSINCE = "If-Modified-Since";  
    
    final protected HttpServletRequest getRequest(){
    	return SpringUtil.getRequest();
    }
    
    final protected HttpServletResponse getResponse(){
    	return SpringUtil.getResponse();
    }
    
    @InitBinder
    public void initBinder(WebDataBinder binder) {
        SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd");
        dateFormat.setLenient(false);
		
        binder.registerCustomEditor(Date.class, new DateEditor());
        
        binder.registerCustomEditor(Timestamp.class, new PropertyEditorSupport() {  
            public void setAsText(String value) {
            	if(StringUtils.isNotBlank(value)){
            		setValue(new Timestamp(Long.valueOf(value)));  
            	}
            }  
        }); 
    }
    
    /**
     * 向客户端输出处理结果
     * @param obj
     */
    final protected void outputData(Object obj){
        //判断输出格式，默认使用JSON
        String callback = this.getRequest().getParameter("callback");
        
        String jsonString = JsonUtil.toJSONString(obj);
        //JSONP
        if(StringUtils.isNotBlank(callback)){
            jsonString = callback + "(" + jsonString + ");";
        }
        ServletUtil.outputText(this.getRequest(), this.getResponse(), jsonString, ServletUtil.CONTENTTYPE_HTML, ServletUtil.CHARTSET_UTF8);
    }
    
    /**
     * 向客户端输出处理结果，封装为R，格式为json，如果request附带callback参赛，在输出jsonp，方法名为callback
     * @param obj
     */
    final protected void output(Object obj){
    	//返回结果
        R rs = null;
        // 如果返回结果是Result
        if (obj instanceof R) {
            rs = (R) obj;
        }
        // 其它类型
        else {
            rs = R.success(obj);
        }
        
        //判断输出格式，默认使用JSON
        String callback = this.getRequest().getParameter("callback");
        
        String jsonString = JsonUtil.toJSONString(rs);
        //JSONP
        if(StringUtils.isNotBlank(callback)){
            jsonString = callback + "(" + jsonString + ");";
        }
        ServletUtil.outputText(this.getRequest(), this.getResponse(), jsonString, ServletUtil.CONTENTTYPE_HTML, ServletUtil.CHARTSET_UTF8);
    }
    
    /**
     * 向客户端输出字符串，编码为UTF-8
     * @param text
     */
    final protected void outputString(String text){
    	ServletUtil.outputText(this.getRequest(), this.getResponse(), text, ServletUtil.CONTENTTYPE_HTML, ServletUtil.CHARTSET_UTF8);
    }
    
    /**
     * 向客户端输出文件
     * @param fileName
     * @param inline
     */
    final protected void outputFile(String fileName, File file, boolean inline){
    	HttpServletRequest request = SpringUtil.getRequest();
    	HttpServletResponse response = SpringUtil.getResponse();
    	long lastModified = file.lastModified();
    	if(inline){
    		long ifModifiedSince = -1;
    		try{
    			ifModifiedSince = request.getDateHeader(HEADER_IFMODSINCE);
    			if(ifModifiedSince>-1 && ifModifiedSince>=lastModified/1000*1000){
    				response.setStatus(HttpServletResponse.SC_NOT_MODIFIED);
        			return;
    			}
    		}
    		catch(Exception e){
    		}
    	}
        try {
        	response.addDateHeader("Last-Modified", lastModified);
            ServletUtil.outputFile(SpringUtil.getRequest(), SpringUtil.getResponse(), fileName, FileUtils.openInputStream(file), inline);
        } catch (IOException e) {
            logger.error("outputFile error", e);
        }
    }
    
    /**
     * 向客户端输出InputStream
     * @param fileName
     * @param input
     * @param inline
     */
    final protected void outputFile(String fileName, InputStream input, boolean inline){
        try {
            ServletUtil.outputFile(SpringUtil.getRequest(), SpringUtil.getResponse(), fileName, input, inline);
        } catch (IOException e) {
            logger.error("outputFile error", e);
        }
    }
    
    /**
	 * 根据名字获取cookie的值
	 * @param name
	 * @return
	 */
	final protected String getCookie(String name){
		return CookieUtil.getCookie(SpringUtil.getRequest(), name);
	}
    
    /**
	 * 设置cookie
	 * @param name  cookie名字
	 * @param value cookie值
	 * @param maxAge cookie生命周期 ,以秒为单位,如果为0则表示这个cookie随着浏览器的关闭即消失
	 * maxAge 可以为正数，表示此cookie从创建到过期所能存在的时间，以秒为单位，此cookie会存储到客户端电脑，以cookie文件形式保存，不论关闭浏览器或关闭电脑，直到时间到才会过期。
	 * 可以为负数，表示此cookie只是存储在浏览器内存里，只要关闭浏览器，此cookie就会消失。maxAge默认值为-1
	 * 还可以为0，表示从客户端电脑或浏览器内存中删除此cookie
	 */
	final protected void setCookie(String name, String value, String domain, int maxAge, boolean httpOnly){
		CookieUtil.setCookie(SpringUtil.getResponse(), name, value, domain, maxAge, httpOnly);
	}
	
	/**
	 * 删除cookie
	 * @param name
	 */
	final protected void deleteCookie(String name){
		CookieUtil.deleteCookie(SpringUtil.getResponse(), name);
	}
	
	/**
	 * 删除所有cookie
	 */
	final protected void cleanCookie(){
		CookieUtil.cleanCookie(SpringUtil.getRequest(), SpringUtil.getResponse());
	}
    
}
